package com.kehao.aspect;

import com.kehao.annotation.AutoFill;
import com.kehao.costant.AutoFillConst;
import com.kehao.enumeration.OperationType;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;

/**
 * @自定义切面，实现自动填充
 */
@Aspect
@Component
public class AutoFillAspect {

    /*
        切入点
     */
    @Pointcut("execution(* com.kehao.service.impl.*.*(..)) && @annotation(com.kehao.annotation.AutoFill)")
    public void autoFillPointCut(){}

    /*
        前置通知
     */
    @Before("autoFillPointCut()")
    public void autoFill(JoinPoint joinPoint) {

        System.out.println("公共字段填充...");

        //获取操作类型
        MethodSignature signature = (MethodSignature) joinPoint.getSignature(); //获取签名对象
        AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class); //获取方法上的注解对象
        OperationType type = autoFill.value();  //获取注解值

        //获取被拦截方法的参数
        Object[] args = joinPoint.getArgs();
        //判断是否为空
        if (args == null && args.length ==0)
            return;

        //默认获取第一个参数
        Object firstArg = args[0];

        //准备赋值的数据
        LocalDateTime now = LocalDateTime.now();

        //todo: 通过反射赋值
        //todo: 使用Lambda优化
        switch (type) {

            case INSERT -> {
                try {
                    Method setEnrollmentDate = firstArg.getClass().getDeclaredMethod(AutoFillConst.SET_ENROLLMENT_DATE, LocalDateTime.class);
                    Method setUpdateTime = firstArg.getClass().getDeclaredMethod(AutoFillConst.SET_UPDATE_TIME, LocalDateTime.class);
                    //通过反射赋值
                    setEnrollmentDate.invoke(firstArg, now);
                    setUpdateTime.invoke(firstArg, now);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            case UPDATE -> {
                try {
                    Method setUpdateTime = firstArg.getClass().getDeclaredMethod(AutoFillConst.SET_UPDATE_TIME, LocalDateTime.class);
                    //通过反射赋值
                    setUpdateTime.invoke(firstArg, now);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            default -> System.out.println("类型不匹配提");
        }


    }
}
